#include"../../include/DictProducer.h"
#include"../../include/SplitEnglish.h"
#include"../../include/SplitToolCppJieba.h"
#include"../../include/ConfigFile.h"

#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
#include<stdio.h>
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;

DictProducer::DictProducer(const string & path)
{
    _files.push_back(path);
    ConfigFile *conf = ConfigFile::getInstance();
    string UnPath = conf->getConf()["stopEnPath"];
    this->_conf = new Configuration(UnPath);
    _cuttor = new SplitEnglish(*_conf);
    if(_cuttor == NULL)
    {
        return ;
    }
    _flag = false;
}

DictProducer::DictProducer(const string &dir,SplitTool *tools)
{
    DIR * curr = opendir(dir.c_str());
    if(!curr)
    {
        perror("opendir");
        return ;
    }
    struct dirent * mdir = NULL;
    while((mdir = readdir(curr))!=NULL)
    {
        string name = mdir->d_name;
        if(name!="."&&name!="..")
        {
            string pathName = dir+"/"+name;
            _files.push_back(pathName);
        }
    }
    closedir(curr);
    _conf = nullptr;
    _cuttor = tools;
    _flag = true;
}
DictProducer::~DictProducer()
{
    if(!_flag)
    {
        if(_cuttor!=nullptr)
        {
            delete _cuttor;
            _cuttor = NULL;
        }
        if(_conf!=nullptr)
        {
            delete _conf;
            _conf = nullptr;
        }
    }
}
void DictProducer::buildEnDict()
{
    cout<<"begin bulid English Dict!"<<endl;
    
    for(string filename:_files)
    {
        fstream fwrite(filename,ios::in);
        if(!fwrite.good())
        {
            cout<<"path error"<<endl;
            return ;
        }
        string lines;
        string text;

        map<string,int> mp;
        while(getline(fwrite,lines))
        {
            text+=lines;
        }
        vector<string> res = this->_cuttor->cut(text);
            for(auto s:res)
            {
                if(mp.find(s)!=mp.end())
                {
                    mp[s]++;
                }
                else{
                    mp.insert(make_pair(s,1));
                }  
            }
        for(auto p:mp)
        {
            this->_dict.push_back(p);
        }
        fwrite.close();
    }

    cout<<"end of the Bulid"<<endl;
}


void DictProducer::buildCnDict()
{
    map<string,int> mp;

    cout<<"begin bulid Chinese Dict!"<<endl;

    for(string fileName:_files)
    {
        fstream fw(fileName,ios::in);
        if(!fw.good())
        {
            cout<<"path error"<<endl;
            return ;
        }
        string lines;
        string text;
 
        while(getline(fw,lines))
        {
            text+=lines;
        }
        vector<string> res = this->_cuttor->cut(text);
        for(string s:res)
        {
            if(mp.find(s) != mp.end())
            {
                mp[s]++;
            }
            else{
                mp.insert(make_pair(s,1));
            }
        }
        fw.close();

        cout<<fileName<<" is ok"<<endl;
    }
    for(auto p:mp)
    {
        this->_dict.push_back(p);
    }

    cout<<"end of the Bulid"<<endl;
}

void DictProducer::storeDict(const char *filePath)
{
    fstream fw(filePath,ios::out | ios::trunc);
    if(!fw.good())
    {
        return ;
    }
    for(auto p:_dict)
    {
        fw<<p.first<<" "<<p.second<<"\n";
    }
    fw.close();

    cout<<"Dict is write!"<<endl;
}
    
void DictProducer::showFiles()const
{
    for(auto path:_files)
    {
        cout<<path<<endl;
    }
}

void DictProducer::showDict()const
{
    for(auto p:_dict)
    {
        cout<<p.first<<" "<<p.second<<endl;
    }

}

void DictProducer::createIndex()
{
    int cnt = 0;
    if(_flag)
    {
        //中文
        cnt = 3;

        cout<<"Bulid Chinese index"<<endl;
    }
    else{
        //英文
        cnt = 1;

        cout<<"Bulid English index"<<endl;
    }
    int line=1;
    for(auto p:_dict)
    {
        string idx;
        if(_flag)
        {
            idx = p.first.substr(0,3);
        }
        else{
            idx = p.first[0];
        }
        _index[idx].insert(line);
        
        line++;
    }

    cout<<"end of the Bulid"<<endl;
}

void DictProducer::storeIndex(const char *filePath)
{
    cout<<"write index"<<endl;

    fstream fw(filePath,ios::out|ios::trunc);
    if(!fw.good())
    {
        cout<<"path error"<<endl;
        return ;
    }
    for(auto p:_index)
    {
        fw<<p.first<<" ";
        for(auto i:p.second)
        {
            fw<<i<<" ";
        }
        fw<<"\n";
    }
    fw.close();

    cout<<"write is ok"<<endl;
}